"""
演示异步处理结果如何通过Qt信号槽传递给GUI
"""

import asyncio
import threading
import time
from PySide6.QtWidgets import QApplication, QMainWindow, QLabel, QPushButton, QVBoxLayout, QWidget, QTextEdit
from PySide6.QtCore import QObject, Signal, Slot, Qt
from event_bus import EventBus as CPPEventBus
from hook_hub import HookHub


class AsyncEventProcessor(QObject):
    """异步事件处理器"""
    # 定义信号
    data_processed = Signal(str, str)  # (event_id, result)
    processing_error = Signal(str, str)  # (event_id, error_message)
    log_message = Signal(str)  # (message)
    
    def __init__(self):
        super().__init__()
        self.cpp_bus = CPPEventBus()
        self.hook_hub = HookHub()
        self._setup_handlers()
        
    def _setup_handlers(self):
        """设置事件处理器"""
        self.cpp_bus.on(0xC0, self._handle_cpp_event)
        
        # 注册同步验证器
        self.hook_hub.register("data_event", self.sync_validator, priority=100)
        
        # 注册异步处理器
        self.hook_hub.register("data_event", self.async_logger, priority=50, is_async=True)
        self.hook_hub.register("data_event", self.async_notifier, priority=10, is_async=True)
        
    def _handle_cpp_event(self, payload: str) -> None:
        """处理C++事件"""
        self.log_message.emit(f"Received C++ event: {payload}")
        # 转发到HookHub处理
        self.hook_hub.emit("data_event", payload=payload)
        
    def sync_validator(self, **kwargs):
        """同步验证器"""
        payload = kwargs.get('payload', '')
        self.log_message.emit(f"Validating: {payload}")
        
        # 简单验证
        if not payload:
            return False
        return True
        
    async def async_logger(self, **kwargs):
        """异步日志处理器"""
        payload = kwargs.get('payload', '')
        self.log_message.emit(f"Logging: {payload}")
        
        # 模拟异步日志操作
        await asyncio.sleep(1)
        
        result = f"Logged: {payload}"
        self.data_processed.emit("logger", result)
        return result
        
    async def async_notifier(self, **kwargs):
        """异步通知处理器"""
        payload = kwargs.get('payload', '')
        self.log_message.emit(f"Sending notification for: {payload}")
        
        # 模拟异步通知操作
        await asyncio.sleep(1.5)
        
        result = f"Notified: {payload}"
        self.data_processed.emit("notifier", result)
        return result
        
    def send_event(self, data: str):
        """发送事件"""
        self.cpp_bus.emit(0xC0, data)
        
    def shutdown(self):
        """关闭"""
        self.cpp_bus.shutdown()


class MainWindow(QMainWindow):
    """主窗口"""
    
    def __init__(self):
        super().__init__()
        self.init_ui()
        self.setup_processor()
        
    def init_ui(self):
        """初始化UI"""
        self.setWindowTitle("Async Processing with Qt Signals/Slots")
        self.setGeometry(100, 100, 600, 400)
        
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        
        layout = QVBoxLayout(central_widget)
        
        self.status_label = QLabel("Ready")
        self.status_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(self.status_label)
        
        self.send_button = QPushButton("Send Async Event")
        self.send_button.clicked.connect(self.send_event)
        layout.addWidget(self.send_button)
        
        self.log_text = QTextEdit()
        self.log_text.setReadOnly(True)
        layout.addWidget(self.log_text)
        
    def setup_processor(self):
        """设置处理器"""
        self.processor = AsyncEventProcessor()
        
        # 连接信号槽
        self.processor.data_processed.connect(self.on_data_processed)
        self.processor.processing_error.connect(self.on_processing_error)
        self.processor.log_message.connect(self.on_log_message)
        
    @Slot()
    def send_event(self):
        """发送事件"""
        self.status_label.setText("Processing...")
        self.send_button.setEnabled(False)
        
        # 在新线程中发送事件
        def run_async():
            self.processor.send_event(f"event_data_{int(time.time())}")
            
        thread = threading.Thread(target=run_async, daemon=True)
        thread.start()
        
        # 启用按钮（因为我们不等待异步处理完成）
        self.send_button.setEnabled(True)
        
    @Slot(str, str)
    def on_data_processed(self, processor_type: str, result: str):
        """数据处理完成"""
        self.status_label.setText(f"Processed by {processor_type}: {result}")
        self.log_text.append(f"[COMPLETED] {processor_type}: {result}")
        
    @Slot(str, str)
    def on_processing_error(self, processor_type: str, error_message: str):
        """处理错误"""
        self.status_label.setText(f"Error in {processor_type}: {error_message}")
        self.log_text.append(f"[ERROR] {processor_type}: {error_message}")
        
    @Slot(str)
    def on_log_message(self, message: str):
        """日志消息"""
        self.log_text.append(f"[LOG] {message}")
        
    def closeEvent(self, event):
        """窗口关闭事件"""
        self.processor.shutdown()
        event.accept()


def main():
    """主函数"""
    import sys
    app = QApplication(sys.argv)
    
    window = MainWindow()
    window.show()
    
    sys.exit(app.exec())


if __name__ == "__main__":
    main()